from typing import Any, List, Optional

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api import deps
from app.models.user import User
from app.schemas.project import (
    ProjectCreate, ProjectUpdate, ProjectResponse,
    PhaseCreate, PhaseUpdate, PhaseResponse,
    MilestoneCreate, MilestoneUpdate, MilestoneResponse,
    TaskCreate, TaskUpdate, TaskResponse,
    TaskDependencyCreate, TaskDependencyResponse,
    TaskCommentCreate, TaskCommentResponse
)
from app.services import project as project_service


router = APIRouter()


# 项目相关路由
@router.get("/", response_model=List[ProjectResponse])
async def read_projects(
    db: AsyncSession = Depends(deps.get_db),
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
    user_projects_only: bool = False,
) -> Any:
    """获取项目列表"""
    user_id = current_user.id if user_projects_only else None
    projects = await project_service.get_projects(
        db, skip=skip, limit=limit, user_id=user_id
    )
    return projects


@router.post("/", response_model=ProjectResponse, status_code=status.HTTP_201_CREATED)
async def create_project(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_in: ProjectCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建新项目"""
    project = await project_service.create_project(
        db=db, obj_in=project_in, creator_id=current_user.id
    )
    return project


@router.get("/{project_id}", response_model=ProjectResponse)
async def read_project(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定项目详情"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    return project


@router.put("/{project_id}", response_model=ProjectResponse)
async def update_project(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    project_in: ProjectUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新项目"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    # 检查权限：只有项目经理或创建者可以更新项目
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    project = await project_service.update_project(db=db, db_obj=project, obj_in=project_in)
    return project


@router.delete("/{project_id}", response_model=ProjectResponse)
async def delete_project(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除项目"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    # 检查权限：只有项目创建者或超级用户可以删除项目
    if project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    project = await project_service.delete_project(db=db, id=project_id)
    return project


# 阶段相关路由
@router.get("/{project_id}/phases", response_model=List[PhaseResponse])
async def read_phases(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取项目阶段列表"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    phases = await project_service.get_phases_by_project(
        db=db, project_id=project_id, skip=skip, limit=limit
    )
    return phases


@router.post("/{project_id}/phases", response_model=PhaseResponse, status_code=status.HTTP_201_CREATED)
async def create_phase(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    phase_in: PhaseCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建项目阶段"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    # 检查权限：只有项目经理或创建者可以添加阶段
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    # 确保阶段关联到正确的项目
    if phase_in.project_id != project_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Phase must be associated with the specified project",
        )
    phase = await project_service.create_phase(db=db, obj_in=phase_in)
    return phase


@router.get("/phases/{phase_id}", response_model=PhaseResponse)
async def read_phase(
    *,
    db: AsyncSession = Depends(deps.get_db),
    phase_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定阶段详情"""
    phase = await project_service.get_phase_by_id(db=db, id=phase_id)
    if not phase:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Phase not found",
        )
    return phase


@router.put("/phases/{phase_id}", response_model=PhaseResponse)
async def update_phase(
    *,
    db: AsyncSession = Depends(deps.get_db),
    phase_id: int,
    phase_in: PhaseUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新阶段"""
    phase = await project_service.get_phase_by_id(db=db, id=phase_id)
    if not phase:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Phase not found",
        )
    project = await project_service.get_project_by_id(db=db, id=phase.project_id)
    # 检查权限：只有项目经理或创建者可以更新阶段
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    phase = await project_service.update_phase(db=db, db_obj=phase, obj_in=phase_in)
    return phase


@router.delete("/phases/{phase_id}", response_model=PhaseResponse)
async def delete_phase(
    *,
    db: AsyncSession = Depends(deps.get_db),
    phase_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除阶段"""
    phase = await project_service.get_phase_by_id(db=db, id=phase_id)
    if not phase:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Phase not found",
        )
    project = await project_service.get_project_by_id(db=db, id=phase.project_id)
    # 检查权限：只有项目经理或创建者可以删除阶段
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    phase = await project_service.delete_phase(db=db, id=phase_id)
    return phase


# 里程碑相关路由
@router.get("/{project_id}/milestones", response_model=List[MilestoneResponse])
async def read_milestones(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取项目里程碑列表"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    milestones = await project_service.get_milestones_by_project(
        db=db, project_id=project_id, skip=skip, limit=limit
    )
    return milestones


@router.post("/{project_id}/milestones", response_model=MilestoneResponse, status_code=status.HTTP_201_CREATED)
async def create_milestone(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    milestone_in: MilestoneCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建项目里程碑"""
    project = await project_service.get_project_by_id(db=db, id=project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    # 检查权限：只有项目经理或创建者可以添加里程碑
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    # 确保里程碑关联到正确的项目
    if milestone_in.project_id != project_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Milestone must be associated with the specified project",
        )
    milestone = await project_service.create_milestone(db=db, obj_in=milestone_in)
    return milestone


@router.get("/milestones/{milestone_id}", response_model=MilestoneResponse)
async def read_milestone(
    *,
    db: AsyncSession = Depends(deps.get_db),
    milestone_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定里程碑详情"""
    milestone = await project_service.get_milestone_by_id(db=db, id=milestone_id)
    if not milestone:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Milestone not found",
        )
    return milestone


@router.put("/milestones/{milestone_id}", response_model=MilestoneResponse)
async def update_milestone(
    *,
    db: AsyncSession = Depends(deps.get_db),
    milestone_id: int,
    milestone_in: MilestoneUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新里程碑"""
    milestone = await project_service.get_milestone_by_id(db=db, id=milestone_id)
    if not milestone:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Milestone not found",
        )
    project = await project_service.get_project_by_id(db=db, id=milestone.project_id)
    # 检查权限：只有项目经理或创建者可以更新里程碑
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    milestone = await project_service.update_milestone(db=db, db_obj=milestone, obj_in=milestone_in)
    return milestone


@router.delete("/milestones/{milestone_id}", response_model=MilestoneResponse)
async def delete_milestone(
    *,
    db: AsyncSession = Depends(deps.get_db),
    milestone_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除里程碑"""
    milestone = await project_service.get_milestone_by_id(db=db, id=milestone_id)
    if not milestone:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Milestone not found",
        )
    project = await project_service.get_project_by_id(db=db, id=milestone.project_id)
    # 检查权限：只有项目经理或创建者可以删除里程碑
    if project.manager_id != current_user.id and project.creator_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    milestone = await project_service.delete_milestone(db=db, id=milestone_id)
    return milestone


# 任务相关路由
@router.get("/tasks", response_model=List[TaskResponse])
async def read_tasks(
    db: AsyncSession = Depends(deps.get_db),
    skip: int = 0,
    limit: int = 100,
    project_id: Optional[int] = None,
    phase_id: Optional[int] = None,
    assignee_id: Optional[int] = None,
    status: Optional[str] = None,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取任务列表，可按项目、阶段、负责人和状态筛选"""
    tasks = await project_service.get_tasks(
        db=db, skip=skip, limit=limit,
        project_id=project_id, phase_id=phase_id,
        assignee_id=assignee_id, status=status
    )
    return tasks


@router.post("/tasks", response_model=TaskResponse, status_code=status.HTTP_201_CREATED)
async def create_task(
    *,
    db: AsyncSession = Depends(deps.get_db),
    task_in: TaskCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建任务"""
    # 检查项目是否存在
    project = await project_service.get_project_by_id(db=db, id=task_in.project_id)
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found",
        )
    # 检查阶段是否存在（如果指定）
    if task_in.phase_id:
        phase = await project_service.get_phase_by_id(db=db, id=task_in.phase_id)
        if not phase or phase.project_id != task_in.project_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid phase for this project",
            )
    # 检查里程碑是否存在（如果指定）
    if task_in.milestone_id:
        milestone = await project_service.get_milestone_by_id(db=db, id=task_in.milestone_id)
        if not milestone or milestone.project_id != task_in.project_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid milestone for this project",
            )
    # 检查父任务是否存在（如果指定）
    if task_in.parent_id:
        parent_task = await project_service.get_task_by_id(db=db, id=task_in.parent_id)
        if not parent_task or parent_task.project_id != task_in.project_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid parent task for this project",
            )
    task = await project_service.create_task(db=db, obj_in=task_in, creator_id=current_user.id)
    return task


@router.get("/tasks/{task_id}", response_model=TaskResponse)
async def read_task(
    *,
    db: AsyncSession = Depends(deps.get_db),
    task_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定任务详情"""
    task = await project_service.get_task_by_id(db=db, id=task_id)
    if not task:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Task not found",
        )
    return task


@router.put("/tasks/{task_id}", response_model=TaskResponse)
async def update_task(
    *,
    db: AsyncSession = Depends(deps.get_db),
    task_id: int,
    task_in: TaskUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新任务"""
    task = await project_service.get_task_by_id(db=db, id=task_id)
    if not task:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Task not found",
        )
    # 检查权限：只有任务负责人、创建者、项目经理或超级用户可以更新任务
    project = await project_service.get_project_by_id(db=db, id=task.project_id)
    if (task.assignee_id != current_user.id and 
        task.creator_id != current_user.id and 
        project.manager_id != current_user.id and 
        not current_user.is_superuser):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    task = await project_service.update_task(db=db, db_obj=task, obj_in=task_in)
    return task


@router.delete("/tasks/{task_id}", response_model=TaskResponse)
async def delete_task(
    *,
    db: AsyncSession = Depends(deps.get_db),
    task_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除任务"""
    task = await project_service.get_task_by_id(db=db, id=task_id)
    if not task:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Task not found",
        )
    # 检查权限：只有任务创建者、项目经理或超级用户可以删除任务
    project = await project_service.get_project_by_id(db=db, id=task.project_id)
    if task.creator_id != current_user.id and project.manager_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    task = await project_service.delete_task(db=db, id=task_id)
    return task